package com.pi.nbcenter.device.service.comm;

import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.pi.base.exception.ServiceException;
import com.pi.base.util.clz.ClassUtil;
import com.pi.config.enumerate.PartnerConfig;
import com.pi.config.service.ConfigService;
import com.pi.nbcenter.base.consistency.SpringContextHolder;
import com.pi.nbcenter.base.errorcode.base.ErrorPartner;
import com.pi.nbcenter.base.errorcode.iot.ErrorIOTDev;
import com.pi.nbcenter.device.entity.auto.IotDeviceInfo;
import com.pi.nbcenter.device.service.pi.internal.PiIotDevService;

public class BaseServiceProvoder {
  private static final Logger logger = LoggerFactory.getLogger(BaseServiceProvoder.class);
  @Autowired
  private PiIotDevService iotDevService;
  @Autowired
  private ConfigService configService;
  
  protected <T>T queryDeviceServiceProvider(String imei, Long sourceId, Class<T> tClz){
    if(StringUtils.isBlank(imei)){
      throw new ServiceException(
          ErrorIOTDev.DEV_IMEI_EMPTY.getKey(),
          ErrorIOTDev.DEV_IMEI_EMPTY.getCode());
    }
    if(null == sourceId){
      IotDeviceInfo iotDevInfo = iotDevService.queryDbDeviceInfoByImei(imei);
      sourceId = iotDevInfo.getPartnerCode();
    }
    return queryServiceProviderBySource(sourceId, tClz);
  }
  
  protected <T>T queryServiceProviderBySource(Long sourceId, Class<T> tClz){
    String lockService;
    try {
      lockService = configService.queryPartnerConfig(sourceId, PartnerConfig.PARTNER_LOCK_SERVICE);
    } catch (Exception e) {
      logger.error("查询锁具能力失败", e);
      lockService = null;
    }
    if(StringUtils.isNotBlank(lockService)){
      Map<String, T> providers = 
          SpringContextHolder.getApplicationContext().getBeansOfType(tClz);
      for(Map.Entry<String, T> entry:providers.entrySet()){
        T provider = entry.getValue();
        Class<?> clz = AopUtils.getTargetClass(provider);
        Service serviceProvider = ClassUtil.getAnnotationOnClass(clz, Service.class);
        if(null != serviceProvider){
          String name = serviceProvider.value();
          if(lockService.indexOf(name) != -1)
            return provider;
        }
      }
    }
 
    throw new ServiceException(
        ErrorPartner.NO_PARTNER_SERVICE_PROVIDED.getKey(),
        ErrorPartner.NO_PARTNER_SERVICE_PROVIDED.getCode());
  }
}
